#ifndef _ROOM_HPP_20120625
#define _ROOM_HPP_20120625

#include "base.hpp"

#include "cmd_type.hpp"
#include "cmd_comm.hpp"

#include "table.hpp"

using namespace cmd;

class Player;

class Room
{
	public :
		struct Id
		{
			TABLEID   _tid;
			SEATID    _sid;

			Id() : _tid(0), _sid(0) {}
		};

	public :
		typedef __gnu_cxx::hash_map<TABLEID, Table*> TableMap;
		typedef TableMap::iterator TableMap_Iter;

	public :
		Room() 
			: _id(0), _online(0), _capacity(0)
		{
		}

		~Room();

		template <typename _Table>
			int init(ROOMID id, TABLENUM table_num);

		Table * find_table(TABLEID id);

		Id select_table(const RoleB & role_b);

		template <typename _FuncObj>
			int execute_all(_FuncObj & obj);

		void enter()        { ++ _online; }
		void leave()        { -- _online; }
		
		bool full() const   { return (_online >= _capacity); }
		bool empty() const  { return (_online <= 0); }

		int online()      const { return _online; }
		int capacity()    const { return _capacity; }

	public :
		ROOMID    _id;
		ROOMNUM   _online;
		ROOMNUM   _capacity;

		TableMap  _table_map;
};

template <typename _Table>
int Room::init(ROOMID id, TABLENUM tables)
{
	_id = id;

	for (int i = 1; i <= tables; ++ i)
	{
		_Table * pTable = new _Table(i, this);
		assert(NULL != pTable);
		_table_map.insert(std::make_pair(i, pTable));

		_capacity += pTable->capacity();
	}
	return 0;
}

template <typename _FuncObj>
int Room::execute_all(_FuncObj & obj)
{
	TableMap_Iter iter = _table_map.begin();
	for (; iter != _table_map.end(); ++ iter)
	{
		if (obj.execute(iter->second) != 0)
		{
			return 1;
		}
	}

	return 0;
}

#endif

